package main

import (
	"net"
	"strings"
)

type User struct {
	Name   string
	Addr   string
	Chan   chan string
	conn   net.Conn
	server *Server
}

// 创建一个用户的 API,
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		Chan:   make(chan string),
		conn:   conn,
		server: server,
	}

	// 启动监听当前 User.Chan 消息的 goroutine,
	go user.ListenMessage()
	return user
}

// 用户的上线业务,
func (this *User) Online() {
	// 用户上线, 将用户加入到 OnlineMap 中摘掉,
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	// 广播当前用户的上线消息,
	this.server.Broadcast(this, "i am online")
}

// 用户的下线业务,
func (this *User) Offline() {
	// 用户下线, 将用户从 OnlineMap 中摘掉,
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	// 广播当前用户的上线消息,
	this.server.Broadcast(this, "i am offline")
}

// 给 user 对应的客户端发送消息, 并不是广播,
func (this *User) SendMsg(msg string) {
	this.conn.Write([]byte(msg))
}

// 用户处理消息的业务,
func (this *User) DoMessage(msg string) {
	if msg == "who" {
		// 查询当前在线所有用户都有哪些,
		this.server.mapLock.Lock()
		for _, user := range this.server.OnlineMap {
			onlineMsg := "[" + user.Addr + "]" + user.Name + ":" + "online...\n"
			this.SendMsg(onlineMsg)
		}
		this.server.mapLock.Unlock()
	} else if msg == "whoami" {
		// 查询自己的用户名,
		this.SendMsg(this.Name + "\n")
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		// 消息格式是 "rename|zhangsan"
		newName := strings.Split(msg, "|")[1]
		// 判断 name 是否存在,
		_, ok := this.server.OnlineMap[newName]
		if ok {
			this.SendMsg("update username failed, the username is exist!")
		} else {
			this.server.mapLock.Lock()
			delete(this.server.OnlineMap, this.Name)
			this.server.OnlineMap[newName] = this
			this.server.mapLock.Unlock()
			this.Name = newName
			this.SendMsg("update username success! " + newName + "\n")
		}
	} else if len(msg) > 4 && msg[:3] == "to|" {
		// 消息格式是 "to|zhangsan|ninhao" 私聊,
		// 1.获取对方的用户名,
		remoteName := strings.Split(msg, "|")[1]
		if remoteName == "" {
			this.SendMsg("message type error, please use to|zhangsan|msg \n")
			return
		}
		// 2.根据用户名得到对方的 user 对象,
		remoteUser, ok := this.server.OnlineMap[remoteName]
		if !ok {
			this.SendMsg("the remoteName is not exist \n")
			return
		}
		// 3.获取消息内容, 通过对方的 user 对象将消息内容发送过去,
		content := strings.Split(msg, "|")[2]
		if content == "" {
			this.SendMsg("message_buf is nil \n")
			return
		}
		remoteUser.SendMsg(this.Name + " say :" + content + "\n")

	} else {
		// 将得到的消息进行广播,
		this.server.Broadcast(this, msg)
	}
}

// 监听当前 User.Chan 的方法, 一旦有消息就直接发送给对端客户端,
func (this *User) ListenMessage() {
	for {
		msg := <-this.Chan
		this.conn.Write([]byte(msg + "\n"))
	}
}
